package com.demo.miya.service.seata.tcc;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.demo.miya.dao.mapper.UserMapper;
import com.demo.miya.model.User;
import io.seata.rm.tcc.api.BusinessActionContext;
import io.seata.rm.tcc.api.BusinessActionContextParameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class SeataTCCServiceImpl extends ServiceImpl<UserMapper, User> implements SeataTCCService {

    @Override
    public void prepare(BusinessActionContext actionContext,
                        @BusinessActionContextParameter(paramName = "userId") Long userId,
                        @BusinessActionContextParameter(paramName = "sleepTime") Long sleepTime) throws InterruptedException {

        if (sleepTime > 10) {
            throw new RuntimeException("sleepTime > 10");
        } else if (sleepTime >= 5) {
            log.info("业务处理中");
            TimeUnit.SECONDS.sleep(sleepTime);
        }
        User user = new User().setUserName("tcc-tx-" + sleepTime).setUserId(userId);
        this.save(user);
    }

    @Override
    public boolean commitMethod(BusinessActionContext actionContext) {
        log.info("执行commit");
        if (actionContext.getActionContext("userId") != null) {
            log.info("用户 {}, 创建成功", actionContext.getActionContext("userId"));
            long currentedTimeMillis = System.currentTimeMillis();
            LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
            wrapper.set(User::getCreateTime, currentedTimeMillis);
            wrapper.eq(User::getUserId, actionContext.getActionContext("userId"));
            this.update(wrapper);
            return true;
        }
        return false;
    }

    @Override
    public boolean rollbackMethod(BusinessActionContext parameterContext) {
        log.info("执行rollback");
        if (parameterContext.getActionContext("userId") != null) {
            log.info("用户 {}, 回滚", parameterContext.getActionContext("userId"));
            LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
            wrapper.set(User::getUserName, "tcc-tx-rollback-" + parameterContext.getActionContext("sleepTime"));
            wrapper.eq(User::getUserId, parameterContext.getActionContext("userId"));
            this.update(wrapper);
            return true;
        }
        return false;
    }
}
